#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

#include "common.h"

static int fd[3] = {-1, -1, -1};
static int dataBit = 8;
static int stopBit = 1;
//static char nEvent = 'N';

extern SystemParam* pgSystemParam;
extern pthread_mutex_t projector_WirelessMic_ttyS_Lock;

static int setBaudRate(struct recvData *recvData, struct packageFilter *pFilter);
static int writeSerialData(struct recvData *recvData, struct packageFilter *pFilter);
static int readSerialData(struct recvData *recvData, struct packageFilter *pFilter);
static int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);

static bool checkMatchCloseCode(unsigned char *pCheckMatch, unsigned char serialDataLen);
static void *checkCenterCtrlMachineStatusThread(void *arg);
static void getCenterCtrlMachineStatus();

//protoSlaveType
enum _protoSlaveType
{
		_setBaudRate 			= 	0x00,
		_writeSerialData 	= 	0x01,
		_readSerialData 	= 	0x02,
};

int initSerialServer()
{
		//if( fd[1] == -1 )
		//		fd[1] = open("/dev/ttyS3",O_RDWR|O_NOCTTY);
				
		if( fd[2] == -1 )
				fd[2] = open("/dev/ttyS4",O_RDWR|O_NOCTTY);	
				
		/*pthread_t ptID;	
		if( pthread_create(&ptID, NULL, checkCenterCtrlMachineStatusThread, (void *)0) != 0 )
		{
				printf("create thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return -1;
		}*/	
		
		return 0;
}

void serialServer(struct recvData *recvData)
{
		//if( fd[0] == -1 )
		//		fd[0] = open("/dev/ttyS1",O_RDWR|O_NOCTTY);	
		//if( fd[1] == -1 )
		//		fd[1] = open("/dev/ttyS3",O_RDWR|O_NOCTTY);
		if( fd[2] == -1 )
				fd[2] = open("/dev/ttyS4",O_RDWR|O_NOCTTY);	
							
		//if(fd[0]< 0 || fd[1] < 0 || fd[2] < 0)
		//{
		//		printf("fd[0]< 0 || fd[1] < 0 || fd[2] < 0 ! fd = %d,%d,%d\n", fd[0],fd[1],fd[2]);	
		//		return;
		//}
				
		if(fd[1] < 0 || fd[2] < 0)
		{
				printf("fd[1] < 0 || fd[2] < 0 ! fd = %d,%d,%d\n", fd[1],fd[2]);	
				return;
		}
							
		if(recvData == NULL)
		{
				printf("recvData == NULL ! {%s(%d)}\n",__FILE__,__LINE__);
				return;	
		}
	
		struct packageFilter filter;
		int ret = explainPackageHead(recvData, &filter);
		if(ret < 0)
		{
				return;	
		}
		
		writeLog("reject !\n", __FILE__, __LINE__);
		return;
		
		switch(filter.protoSlaveType)
		{
				case _setBaudRate:
				{
						setBaudRate(recvData, &filter);
						break;	
				}
				case _writeSerialData:
				{
						writeSerialData(recvData, &filter);
						break;
				}
				case _readSerialData:
				{
						readSerialData(recvData, &filter);	
						break;
				}
				default:
				{
						printf("filter.protoSlaveType not right ! filter.protoSlaveType = %d\n", filter.protoSlaveType);
						break;	
				}
		}
}

static int setBaudRate(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto 2,0 pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 7)
		{
				printf("proto 2,0 pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL !\n");
				return -3;	
		}
		
		int ret;
		unsigned char serialNum = pFilter->pData[0];
		if(serialNum > 2 || serialNum <= 0)
		{
				printf("serialNum > 2 ! serialNum  = %d\n", serialNum);	
				return -4;
		}
		
		unsigned short baudRate;
		ret = changeByteToUShort(baudRate, pFilter->pData + 1);
		if(ret != 0)
		{
				printf("pFilter->pData + 1 == NULL !\n");
				return -5;	
		}
		//printf("setBaudRate = %d\n", serialNum);
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData + 3, 4);
		
		unsigned char returnRet = 0;
		ret = set_opt(fd[serialNum], baudRate, dataBit, pgSystemParam->projectorParitycheck, stopBit);
		if(ret != 0)
		{
				printf("set_opt fail ! ret = %d\n", ret);
				returnRet = 1;
		}
		
		unsigned char dataDirection = 0x01;
		unsigned short dataLen = 6;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + 6;
		for(unsigned char i=0; i<headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		recvData->buf[headLen] = serialNum;
		recvData->buf[headLen + 1] = returnRet;
		memcpy(recvData->buf + headLen + 2, privateData, 4);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
}

static int writeSerialData(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto 2,1 pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen < 6)
		{
				printf("proto 2,1 pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL !\n");
				return -3;	
		}
	
		unsigned char serialNum = pFilter->pData[0];
		if(serialNum > 5 || serialNum <= 0)
		{
				printf("serialNum > 5 ! serialNum  = %d\n", serialNum);	
				return -4;
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData + 1, 4);
		
		unsigned char delaySec = 0;	
		unsigned char action = 0;	//1 shut down, 2 reboot
		unsigned char returnRet = 0;
		
		if(serialNum < 3)
		{
				int aimFd = fd[serialNum]; 

				//bool needReboot = false;
				unsigned char *pSerialData = pFilter->pData + 5;
				int serialDataLen = pFilter->dataLen - 5;
				
				int ret;
				
				ret = write(aimFd, pSerialData, serialDataLen);
				if(ret < 0)
				{
						printf("serial write error ! ret = %d\n", ret);	
						returnRet = 1;
				}
				
				//if(returnRet == 0 && serialNum == 2 && serialDataLen >= 6)
				//{
				//		unsigned char *pCheckMatch = pSerialData;
				//		//needReboot = checkMatchCloseCode(pSerialData, serialDataLen);
				//}
		}
		else
		{
				if(serialNum == 4)
				{
						delaySec = pFilter->pData[5];
						action = 1;
				}
				else if(serialNum == 5)
				{
						delaySec = pFilter->pData[5];
						action = 2;
				}
		}
		
		unsigned char dataDirection = 0x01;
		unsigned short dataLen = 6;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		for(unsigned char i=0; i<headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		recvData->buf[headLen] = serialNum;
		recvData->buf[headLen + 1] = returnRet;
		memcpy(recvData->buf + headLen + 2, privateData, 4);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		
		//if(needReboot)
		//{
				//printf("prepare to reboot !{%s,%d}\n", __FILE__,__LINE__);	
				//sleep(1);
				//system("reboot");
		//}
}

static bool checkMatchCloseCode(unsigned char *pCheckMatch, unsigned char serialDataLen)
{
		static const unsigned char code[] = {0xFE, 0x03, 0x01, 0x01, 0x00, 0x01};
			
		unsigned char addValue = 1;
		unsigned char i = 0;
		while(i < serialDataLen)
		{
				if(pCheckMatch[0] == code[0])
				{
						if(pCheckMatch[1] == code[1])
						{
								if(pCheckMatch[2] = code[2])
								{
										if(pCheckMatch[3] == code[3])
										{
												if(pCheckMatch[4] == code[4])
												{
														if(pCheckMatch[5] == code[5])	return true;
														else addValue = 5;
												}	
												else addValue = 4;
										}	
										else addValue = 3;
								}
								else addValue = 2;
						}
						else addValue = 1;
				}
				else addValue = 1;
				
				i += addValue;
				pCheckMatch += addValue;
		}
		
		return false;
}

static int readSerialData(struct recvData *recvData, struct packageFilter *pFilter)
{
		static unsigned char readBuf[1024] = {0};
		
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto 2,2 pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 9)
		{
				printf("proto 2,2 pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL !\n");
				return -3;	
		}
		
		int ret;
		unsigned char serialNum = pFilter->pData[0];
		if(serialNum > 2 || serialNum <= 0)
		{
				printf("serialNum > 2 ! serialNum  = %d\n", serialNum);	
				return -4;
		}
		
		int aimFd = fd[serialNum]; 
		unsigned short estimateDataLen;
		ret = changeByteToUShort(estimateDataLen, pFilter->pData + 1);
		if(ret != 0)
		{
				printf("pFilter->pData + 1 == NULL !\n");
				return -5;	
		}
		
		if(estimateDataLen > 1000)
		{
				printf("estimateDataLen > 1000, it is not support !\n");
				return -6;	
		}
		
		unsigned short timeout;
		ret = changeByteToUShort(timeout, pFilter->pData + 3);
		if(ret != 0)
		{
				printf("pFilter->pData + 3 == NULL !\n");
				return -7;	
		}
		
		if(timeout < 100)
		{
				printf("timeout < 100 is not significant !\n");	
		}
		
		if(timeout > 25500)
		{
				printf("timeout > 25500 ! it will be cut down to 25500 !\n");
				timeout = 25500;
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData + 5, 4);
		
		/*
		struct termios tio;
		ret = tcgetattr(aimFd, &tio);
		if(ret != 0)
		{
				printf("tcgetattr error !\n");
				return -8;
		}
		
		tio.c_cc[VTIME] = timeout/100;		
		ret = tcsetattr(aimFd,TCSANOW,&tio);
		if(ret != 0)
		{
				printf("tcsetattr error !\n");
				return -9;
		}
		
		unsigned char returnRet = 0;
		unsigned short realReadDataLen = 0;
		ret = read(aimFd, readBuf, estimateDataLen);
		if(ret < 0)
		{
				printf("read error !\n");
				returnRet = 1;
		}
		*/
		
		struct pollfd pollflag;	
		unsigned char returnRet = 0;
		unsigned short realReadDataLen = 0;
		
		pollflag.fd     = aimFd;
	  pollflag.events = POLLIN;
		  
		ret = poll( &pollflag, 1, timeout );
		
		if( ret <= 0 )
		{
				returnRet = 1;
		}	
		else if( ( ret = read(aimFd,readBuf,estimateDataLen) ) <= 0 )	
		{
				returnRet = 1;
				realReadDataLen = 0;
		}
		else
		{
				realReadDataLen = (unsigned short)ret;
		}
		printf("timeout:%d,estimateDataLen:%d,realReadDataLen:%d\n",timeout,estimateDataLen,realReadDataLen);
		unsigned char dataDirection = 0x01;
		unsigned short dataLen = 6 + realReadDataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		for(unsigned char i=0; i<headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		recvData->buf[headLen] = serialNum;
		recvData->buf[headLen + 1] = returnRet;
		memcpy(recvData->buf + headLen + 2, privateData, 4);
		
		memcpy(recvData->buf + headLen + 6, readBuf, realReadDataLen);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
}


//static int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
static int set_opt(int fd,int nSpeed, int nBits, unsigned char nEvent, int nStop)
{
    struct termios newtio,oldtio;
    if  ( tcgetattr( fd,&oldtio)  !=  0) 
    { 
        //perror("SetupSerial 1");
        return -1;
    }
    bzero( &newtio, sizeof( newtio ) );
    newtio.c_cflag  |=  CLOCAL | CREAD; 
    newtio.c_cflag &= ~CSIZE; 

    switch( nBits )
    {
    case 7:
        newtio.c_cflag |= CS7;
        break;
    case 8:
        newtio.c_cflag |= CS8;
        break;
    }

    switch( nEvent )
    {
    //case 'O':                     //
    case 1:
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        newtio.c_iflag |= (INPCK | ISTRIP);
        break;
    //case 'E':                     //
    case 2:
        newtio.c_iflag |= (INPCK | ISTRIP);
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~PARODD;
        break;
    //case 'N':                    //
    case 0:
        newtio.c_cflag &= ~PARENB;
        break;
    }

switch( nSpeed )
    {
    case 1200:
        cfsetispeed(&newtio, B1200);
        cfsetospeed(&newtio, B1200);  
        break;
    case 2400:
        cfsetispeed(&newtio, B2400);
        cfsetospeed(&newtio, B2400);
        break;
    case 4800:
        cfsetispeed(&newtio, B4800);
        cfsetospeed(&newtio, B4800);
        break;
    case 9600:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    case 14400:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    case 19200:
        cfsetispeed(&newtio, B19200);
        cfsetospeed(&newtio, B19200);
        break;
    case 38400:
        cfsetispeed(&newtio, B38400);
        cfsetospeed(&newtio, B38400);
        break;
    case 57600:
        cfsetispeed(&newtio, B57600);
        cfsetospeed(&newtio, B57600);
        break;
    case 115200:
        cfsetispeed(&newtio, B115200);
        cfsetospeed(&newtio, B115200);
        break;
    default:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    }
    if( nStop == 1 )
    {
        newtio.c_cflag &=  ~CSTOPB;
    }
    else if ( nStop == 2 )
    {
        newtio.c_cflag |=  CSTOPB;
    }
    newtio.c_cc[VTIME]  = 0;
    newtio.c_cc[VMIN] = 0;	
    tcflush(fd,TCIFLUSH);
    if((tcsetattr(fd,TCSANOW,&newtio))!=0)
    {
        //perror("com set error");
        return -2;
    }
    //printf("set done!\n");
    return 0;
}

/*#define CTRL_SERIAL_NUM 2
#define SERIAL_NAME "/dev/ttyS4"
#define DELAY_TIME 2
#define DATA_TIME 10
#define BAUD_RATE 1200
static void *checkCenterCtrlMachineStatusThread(void *arg)
{
		static sem_t sem_tmp;
		struct timespec ts;
		struct timeval  tv;	
		int ret;
		
		if( sem_init(&(sem_tmp), 1, 0) != 0   ) 
		{
				printf("sem_init failure {%s(%d)}\n",__FILE__,__LINE__);	
				return NULL;
		}
		
		while( !IsExit() )
		{
				gettimeofday(&tv, NULL); 
			  ts.tv_sec  = tv.tv_sec + DELAY_TIME;
		    ts.tv_nsec = tv.tv_usec * 1000;		
		    
		    sem_timedwait(&(sem_tmp),&ts);
		    
		    getCenterCtrlMachineStatus(); 
		}
}

static void getCenterCtrlMachineStatus()
{
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
							
		struct pollfd pollflag;	
		int ret;
		unsigned short realReadDataLen = 0;
		static unsigned char readBuf[12];
		
		pollflag.fd     = fd[CTRL_SERIAL_NUM];
	  pollflag.events = POLLIN;
		  
		ret = poll( &pollflag, 1, DATA_TIME);
		
		if( ret <= 0 )
		{
				//printf("ret < 0 {%s,%d}\n", __FILE__, __LINE__);
				return;
		}	
		
		if( ( ret = read(fd[CTRL_SERIAL_NUM], readBuf, 6) ) <= 0 )	
		{
				printf("ret <= 0, ret = %d\n", ret);
				return;
		}
		
		if(ret != 6)
		{
				printf("ret != 6, ret = %d\n", ret);
				return;
		}
		
		if(readBuf[0] == 0xFC && readBuf[1] == 0x00 && readBuf[3] == 0x00 && readBuf[5] == 0xFF)
		{
				if(readBuf[2] == 0x01 && readBuf[4] == 0x01)
				{
						pgSystemParam->centerCtrlMachineIsOpen = true;	
						printf("recv system open return code !\n");
				}	
				else if(readBuf[2] == 0x02 && readBuf[4] == 0x02)
				{
						pgSystemParam->centerCtrlMachineIsOpen = false;
						printf("recv system close return code !\n");
				}
				else
				{
						printf("6 bytes is not right ! {%s, %d}\n", __FILE__, __LINE__);	
						printf("readBuf = %x,%x,%x,%x,%x,%x\n", readBuf[0],readBuf[1],readBuf[2],readBuf[3],readBuf[4],readBuf[5]);
				}
		}
}

void openCenterCtrlMachine()
{
		printf("into openCenterCtrlMachine\n");
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
		
		int aimFd = fd[CTRL_SERIAL_NUM];
		int ret;
		static char logBuf[60];
		ret = set_opt(aimFd, BAUD_RATE, dataBit, nEvent, stopBit);
		if(ret < 0)
		{
				sprintf(logBuf, "set baudRate fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return;	
		}
		
		static const unsigned char openCode[6] = {0xFE, 0x03, 0x00, 0x01, 0x00, 0x01};
		static const int codeSize = sizeof(openCode);
		ret = write(aimFd, openCode, codeSize);
		
		if(ret !=  codeSize)
		{
				sprintf(logBuf, "write open code fail ! ret = %d\n", ret);	
				writeLog(logBuf, __FILE__, __LINE__);
		}
		else
		{
				pgSystemParam->centerCtrlMachineIsOpen = true;
		}
}

void closeCenterCtrlMachine()
{
		printf("into closeCenterCtrlMachine\n");
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
		
		int aimFd = fd[CTRL_SERIAL_NUM];
		int ret;
		static char logBuf[60];
		ret = set_opt(aimFd, BAUD_RATE, dataBit, nEvent, stopBit);
		if(ret < 0)
		{
				printf("set baudRate fail ! ret = %d, {%s,%d}\n", ret, __FILE__, __LINE__);
				return;	
		}
		
		static const unsigned char closeCode[6] = {0xFE, 0x03, 0x00, 0x02, 0x00, 0x02};
		static const int codeSize = sizeof(closeCode);
		ret = write(aimFd, closeCode, codeSize);
		
		if(ret !=  codeSize)
		{
				sprintf(logBuf, "write close code fail ! ret = %d\n", ret);	
				writeLog(logBuf, __FILE__, __LINE__);
		}
		else
		{
				pgSystemParam->centerCtrlMachineIsOpen = false;
				
				printf("prepare to reboot !\n");
				system("reboot");
		}
}*/


//20160530 change
#define CTRL_SERIAL_NUM 2
#define SERIAL_NAME "/dev/ttyS4"
//#define BAUD_RATE 1200
#define SEND_OEPN_CODE_TIMES		2
#define SEND_CODE_TIME_INTERVAL_S	2
void openProjector()
{
		printf("into openProjector\n");
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
		
		if(!pgSystemParam)
		{
				printf("pgSystemParam == NULL {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
		
		if(pgSystemParam->projectorOpenCodeNum == 0)
		{
				printf("projectorOpenCodeNum == 0 {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
			
		CtrlCodeType openCode;
		unsigned char openCodeNum;
		
		pthread_mutex_lock(&(pgSystemParam->projectorCodeLock));	
		memcpy(openCode, pgSystemParam->projectorOpenCode, PROJECTOR_CODE_MAX_LEN);
		openCodeNum = pgSystemParam->projectorOpenCodeNum;
		pthread_mutex_unlock(&(pgSystemParam->projectorCodeLock));
		
		printf("openProjector:prepare to get projector_WirelessMic_ttyS_Lock\n");
		pthread_mutex_lock(&projector_WirelessMic_ttyS_Lock);
		
		printf("openProjector:prepare to set pgSystemParam->projectorBaud,pariry = %d,%d\n", pgSystemParam->projectorBaud,pgSystemParam->projectorParitycheck);
		int ret = set_opt(fd[CTRL_SERIAL_NUM], pgSystemParam->projectorBaud, dataBit, pgSystemParam->projectorParitycheck, stopBit);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "set baudRate fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return;	
		}
		
		printf("prepare to write open code\n");
		for (int i = 0; i < SEND_OEPN_CODE_TIMES; i ++)
		{
			printf("prepare to write the %d time\n", i);
			write(fd[CTRL_SERIAL_NUM], openCode, openCodeNum);
			sleep(SEND_CODE_TIME_INTERVAL_S);
		}

		pthread_mutex_unlock(&projector_WirelessMic_ttyS_Lock);
		
}

void closeProjector()
{
		printf("into closeProjector\n");
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
		
		if(!pgSystemParam)
		{
				printf("pgSystemParam == NULL {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
		
		if(pgSystemParam->projectorCloseCodeNum == 0)
		{
				printf("projectorOpenCodeNum == 0 {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
			
		CtrlCodeType closeCode;
		unsigned char closeCodeNum;
		
		pthread_mutex_lock(&(pgSystemParam->projectorCodeLock));	
		memcpy(closeCode, pgSystemParam->projectorCloseCode, PROJECTOR_CODE_MAX_LEN);
		closeCodeNum = pgSystemParam->projectorCloseCodeNum;
		pthread_mutex_unlock(&(pgSystemParam->projectorCodeLock));
		
		
		printf("closeProjector:prepare to get projector_WirelessMic_ttyS_Lock\n");
		pthread_mutex_lock(&projector_WirelessMic_ttyS_Lock);
		
		printf("closeProjector:prepare to set pgSystemParam->projectorBaud,pariry = %d,%d\n", pgSystemParam->projectorBaud,pgSystemParam->projectorParitycheck);
		int ret = set_opt(fd[CTRL_SERIAL_NUM], pgSystemParam->projectorBaud, dataBit, pgSystemParam->projectorParitycheck, stopBit);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "set baudRate fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return;	
		}
	
		printf("prepare to write close code\n");
		write(fd[CTRL_SERIAL_NUM], closeCode, closeCodeNum);
		
		pthread_mutex_unlock(&projector_WirelessMic_ttyS_Lock);
}

void setProjectVga()
{
		printf("into closeProjector\n");
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
		
		if(!pgSystemParam)
		{
				printf("pgSystemParam == NULL {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
		
		if(pgSystemParam->projectorVgaCodeNum == 0)
		{
				printf("projectorVgaCodeNum == 0 {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
			
		CtrlCodeType vgaCode;
		unsigned char vgaCodeNum;
		
		pthread_mutex_lock(&(pgSystemParam->projectorCodeLock));	
		memcpy(vgaCode, pgSystemParam->projectorVgaCode, PROJECTOR_CODE_MAX_LEN);
		vgaCodeNum = pgSystemParam->projectorCloseCodeNum;
		pthread_mutex_unlock(&(pgSystemParam->projectorCodeLock));
		
		
		printf("setProjectVga:prepare to get projector_WirelessMic_ttyS_Lock\n");
		pthread_mutex_lock(&projector_WirelessMic_ttyS_Lock);
		
		printf("setProjectVga:prepare to set pgSystemParam->projectorBaud,pariry = %d,%d\n", pgSystemParam->projectorBaud,pgSystemParam->projectorParitycheck);
		int ret = set_opt(fd[CTRL_SERIAL_NUM], pgSystemParam->projectorBaud, dataBit, pgSystemParam->projectorParitycheck, stopBit);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "set baudRate fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return;	
		}
		
		printf("prepare to write vga code\n");
		write(fd[CTRL_SERIAL_NUM], vgaCode, vgaCodeNum);
		
		pthread_mutex_unlock(&projector_WirelessMic_ttyS_Lock);
	
}

void setProjectHdmi()
{
		printf("into setProjectHdmi\n");
		if( fd[CTRL_SERIAL_NUM] < 0)
		{
				fd[CTRL_SERIAL_NUM] = open(SERIAL_NAME,O_RDWR|O_NOCTTY);	
				if(fd[CTRL_SERIAL_NUM] < 0)
				{
						printf("fd[CTRL_SERIAL_NUM] < 0 fd[CTRL_SERIAL_NUM] = %d\n", fd[CTRL_SERIAL_NUM]);
						return;	
				}
		}
		
		if(!pgSystemParam)
		{
				printf("pgSystemParam == NULL {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
		
		if(pgSystemParam->projectorHdmiCodeNum == 0)
		{
				printf("projectorHdmiCodeNum == 0 {%s,%d}\n", __FILE__, __LINE__);
				return;
		}
			
		CtrlCodeType hdmiCode;
		unsigned char hdmiCodeNum;
		
		pthread_mutex_lock(&(pgSystemParam->projectorCodeLock));	
		memcpy(hdmiCode, pgSystemParam->projectorHdmiCode, PROJECTOR_CODE_MAX_LEN);
		hdmiCodeNum = pgSystemParam->projectorHdmiCodeNum;
		pthread_mutex_unlock(&(pgSystemParam->projectorCodeLock));
		
		
		printf("setProjectHdmi:prepare to get projector_WirelessMic_ttyS_Lock\n");
		pthread_mutex_lock(&projector_WirelessMic_ttyS_Lock);
		
		printf("setProjectHdmi:prepare to set pgSystemParam->projectorBaud,pariry = %d,%d\n", pgSystemParam->projectorBaud,pgSystemParam->projectorParitycheck);
		int ret = set_opt(fd[CTRL_SERIAL_NUM], pgSystemParam->projectorBaud, dataBit, pgSystemParam->projectorParitycheck, stopBit);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "set baudRate fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return;	
		}
		printf("prepare to write hdmi code\n");
		write(fd[CTRL_SERIAL_NUM], hdmiCode, hdmiCodeNum);
		
		pthread_mutex_unlock(&projector_WirelessMic_ttyS_Lock);
}